home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / russell / gc.lha / dynamic_load.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  4KB  |  143 lines

  1. /*
  2.  * Copyright (c) 1991-1993 by Xerox Corporation.  All rights reserved.
  3.  *
  4.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  5.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  6.  *
  7.  * Permission is hereby granted to copy this garbage collector for any purpose,
  8.  * provided the above notices are retained on all copies.
  9.  * Author: Bill Janssen
  10.  * Modified by: Hans Boehm
  11.  */
  12.  
  13. /*
  14.  * This is incredibly OS specific code for tracking down data sections in
  15.  * dynamic libraries.  There appears to be no way of doing this quickly
  16.  * without groveling through undocumented data structures.  We would argue
  17.  * that this is a bug in the design of the dlopen interface.  THIS CODE
  18.  * MAY BREAK IN FUTURE OS RELEASES.  If this matters to you, don't hesitate
  19.  * to let your vendor know ...
  20.  */
  21. #include "gc_private.h"
  22. #ifdef DYNAMIC_LOADING
  23. #if !(defined(M68K) && defined(SUNOS)) && !defined(SPARC)
  24.  --> We only know how to find data segments of dynamic libraries under SunOS 4.X
  25. #endif
  26.  
  27. #include <stdio.h>
  28. #if defined SUNOS5
  29. #   include <sys/elf.h>
  30. #   include <dlfcn.h>
  31. #   include <link.h>
  32. #else
  33. #   include <dlfcn.h>
  34. #   include <link.h>
  35. #   include <a.out.h>
  36.   /* struct link_map field overrides */
  37. #   define l_next    lm_next
  38. #   define l_addr    lm_addr
  39. #   define l_name    lm_name
  40. # endif
  41.  
  42.  
  43. #ifdef SUNOS5
  44.  
  45. static struct link_map *
  46. GC_FirstDLOpenedLinkMap()
  47. {
  48.     extern Elf32_Dyn _DYNAMIC;
  49.     Elf32_Dyn *dp;
  50.     struct r_debug *r;
  51.     static struct link_map * cachedResult = 0;
  52.  
  53.     if( &_DYNAMIC == 0) {
  54.         return(0);
  55.     }
  56.     if( cachedResult == 0 ) {
  57.         int tag;
  58.         for( dp = ((Elf32_Dyn *)(&_DYNAMIC)); (tag = dp->d_tag) != 0; dp++ ) {
  59.             if( tag == DT_DEBUG ) {
  60.                 struct link_map *lm
  61.                         = ((struct r_debug *)(dp->d_un.d_ptr))->r_map;
  62.                 if( lm != 0 ) cachedResult = lm->l_next; /* might be NIL */
  63.                 break;
  64.             }
  65.         }
  66.     }
  67.     return cachedResult;
  68. }
  69.  
  70. # endif
  71.  
  72. # ifdef SUNOS4
  73.  
  74. static struct link_map *
  75. GC_FirstDLOpenedLinkMap()
  76. {
  77.     extern struct link_dynamic _DYNAMIC;
  78.  
  79.     if( &_DYNAMIC == 0) {
  80.         return(0);
  81.     }
  82.     return(_DYNAMIC.ld_un.ld_1->ld_loaded);
  83. }
  84.  
  85.  
  86. # endif
  87.  
  88. /* Add dynamic library data sections to the root set.        */
  89. # if !defined(PCR) && defined(THREADS)
  90.     --> fix mutual exclusion with dlopen
  91. # endif
  92. void GC_register_dynamic_libraries()
  93. {
  94.   struct link_map *lm = GC_FirstDLOpenedLinkMap();
  95.   
  96.  
  97.   for (lm = GC_FirstDLOpenedLinkMap();
  98.        lm != (struct link_map *) 0;  lm = lm->l_next)
  99.     {
  100. #     ifdef SUNOS4
  101.     struct exec *e;
  102.      
  103.         e = (struct exec *) lm->lm_addr;
  104.         GC_add_roots_inner(
  105.                   ((char *) (N_DATOFF(*e) + lm->lm_addr)),
  106.             ((char *) (N_BSSADDR(*e) + e->a_bss + lm->lm_addr)));
  107. #     endif
  108. #     ifdef SUNOS5
  109.     Elf32_Ehdr * e;
  110.         Elf32_Phdr * p;
  111.         unsigned long offset;
  112.         char * start;
  113.         register int i;
  114.         
  115.     e = (Elf32_Ehdr *) lm->l_addr;
  116.         p = ((Elf32_Phdr *)(((char *)(e)) + e->e_phoff));
  117.         offset = ((unsigned long)(lm->l_addr));
  118.         for( i = 0; i < e->e_phnum; ((i++),(p++)) ) {
  119.           switch( p->p_type ) {
  120.             case PT_LOAD:
  121.               {
  122.                 if( !(p->p_flags & PF_W) ) break;
  123.                 start = ((char *)(p->p_vaddr)) + offset;
  124.                 GC_add_roots_inner(
  125.                   start,
  126.                   start + p->p_memsz
  127.                 );
  128.               }
  129.               break;
  130.             default:
  131.               break;
  132.           }
  133.     }
  134. #     endif
  135.     }
  136. }
  137.  
  138. #else
  139. void GC_register_dynamic_libraries(){}
  140.  
  141. int GC_no_dynamic_loading;
  142. #endif
  143.